// 03_functions_and_scope.rs
// 演示 Rust 中的函数与作用域概念

// 1. 函数定义与调用
// 函数使用 fn 关键字定义
// 将原来的 main 函数改为公共的 run 函数
pub fn run() {
    println!("程序开始执行");
    
    // 调用函数
    greet();
    
    // 调用带参数的函数
    greet_person("Alice");
    
    // 调用带返回值的函数
    let result = add(5, 3);
    println!("5 + 3 = {}", result);
    
    // 调用表达式风格的函数
    let result2 = multiply(4, 6);
    println!("4 * 6 = {}", result2);
    
    // 2. 作用域（Scope）
    // 作用域是程序中一个项目在其中有效的范围
    { // 开始一个新的作用域
        let inner_var = "我在内部作用域中";
        println!("{}", inner_var);
        
        // 内部作用域可以访问外部作用域的变量
        let outer_var = "我也是内部变量";
        println!("内部作用域也可以定义新变量: {}", outer_var);
    } // 内部作用域结束，inner_var 和 outer_var 不再有效
    
    // 以下代码会导致编译错误，因为 inner_var 不在当前作用域内
    // println!("{}", inner_var); // 取消注释这行会导致编译错误
    
    // 3. 变量遮蔽
    let shadow_var = 5;
    println!("shadow_var 的初始值: {}", shadow_var);
    
    { // 新的作用域
        let shadow_var = "现在是字符串类型";
        println!("内部作用域中的 shadow_var: {}", shadow_var);
        // 这里的 shadow_var 遮蔽了外部作用域的同名变量
        // 注意：变量遮蔽允许改变类型
    }
    
    // 外部作用域的 shadow_var 未受影响
    println!("回到外部作用域，shadow_var: {}", shadow_var);
    
    // 4. 函数参数与返回值的更多示例
    let (sum, product) = calculate(10, 20);
    println!("10 + 20 = {}, 10 * 20 = {}", sum, product);
    
    // 5. 提前返回（early return）
    let check_result = check_positive(-5);
    println!("检查结果: {}", check_result);
    
    let check_result2 = check_positive(15);
    println!("检查结果: {}", check_result2);
    
    println!("程序执行结束");
}

// 基本函数定义
fn greet() {
    println!("Hello, Rust!");
}

// 带参数的函数
fn greet_person(name: &str) {
    println!("Hello, {}!", name);
}

// 带返回值的函数
fn add(x: i32, y: i32) -> i32 {
    // 注意：Rust 中函数的最后一个表达式的结果就是函数的返回值
    // 不需要使用 return 关键字（除非需要提前返回）
    x + y
}

// 使用表达式风格的函数定义
fn multiply(x: i32, y: i32) -> i32 {
    // 这里使用了显式的 return 语句
    return x * y;
}

// 返回多个值（使用元组）
fn calculate(a: i32, b: i32) -> (i32, i32) {
    let sum = a + b;
    let product = a * b;
    (sum, product) // 返回元组
}

// 提前返回示例
fn check_positive(number: i32) -> bool {
    if number <= 0 {
        println!("数字 {} 不是正数", number);
        return false; // 提前返回
    }
    
    // 如果执行到这里，说明 number > 0
    println!("数字 {} 是正数", number);
    true
}